import React, { createContext, useState, useContext, useEffect, useCallback, useRef } from 'react';
import modelService from '../services/modelService';
import fileService from '../services/fileService';

const ModelContext = createContext();

export const useModelContext = () => useContext(ModelContext);

export const ModelProvider = ({ children }) => {
    const [models, setModels] = useState([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    // 文件操作状态
    const [fileLoading, setFileLoading] = useState(false);
    const [fileError, setFileError] = useState(null);
    const [uploadProgress, setUploadProgress] = useState(0);
    // 几何体类型
    const [geometryTypes, setGeometryTypes] = useState([]);
    const [geometryTypesLoading, setGeometryTypesLoading] = useState(false);
    const [geometryTypesError, setGeometryTypesError] = useState(null);

    // 使用useRef避免重复初始化
    const isInitialized = useRef(false);

    // 获取所有模型
    const fetchModels = useCallback(async () => {
        console.log('[ModelContext] 开始获取所有模型');
        setLoading(true);
        setError(null);
        try {
            const response = await modelService.getModels();
            console.log('[ModelContext] 获取模型成功，数量:', response.data?.length || 0);
            setModels(response.data || []);
        } catch (err) {
            console.error('[ModelContext] 获取模型失败:', err);
            setError('获取模型失败，请稍后再试');
        } finally {
            setLoading(false);
        }
    }, []);

    // 获取几何体类型
    const fetchGeometryTypes = useCallback(async () => {
        console.log('[ModelContext] 开始获取几何体类型');
        setGeometryTypesLoading(true);
        setGeometryTypesError(null);
        try {
            const response = await modelService.getGeometryTypes();
            console.log('[ModelContext] 获取几何体类型成功:', response.data?.length || 0);
            setGeometryTypes(response.data || []);
        } catch (err) {
            console.error('[ModelContext] 获取几何体类型失败:', err);
            setGeometryTypesError('获取几何体类型失败，请稍后再试');
        } finally {
            setGeometryTypesLoading(false);
        }
    }, []);

    // 创建新模型
    const createModel = useCallback(async (modelData) => {
        console.log('[ModelContext] 开始创建新模型:', modelData.name);
        setLoading(true);
        setError(null);
        try {
            const response = await modelService.createModel(modelData);
            console.log('[ModelContext] 创建模型成功:', response.data?.modelId || response.data?.data?.id);
            // 添加新模型到状态
            await fetchModels(); // 重新获取所有模型
            return response;
        } catch (err) {
            console.error('[ModelContext] 创建模型失败:', err);
            setError('创建模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 创建外部模型
    const createExternalModel = useCallback(async (modelData) => {
        console.log('[ModelContext] 开始创建外部模型:', modelData.name);
        setLoading(true);
        setError(null);
        try {
            const response = await fileService.createExternalModel(modelData);
            console.log('[ModelContext] 创建外部模型成功:', response.data?.modelId || response.data?.data?.model?.id);
            // 刷新模型列表
            await fetchModels();
            return response;
        } catch (err) {
            console.error('[ModelContext] 创建外部模型失败:', err);
            setError('创建外部模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 创建几何体模型
    const createGeometryModel = useCallback(async (modelData) => {
        console.log('[ModelContext] 开始创建几何体模型');
        setLoading(true);
        setError(null);
        try {
            // 确保有geometry对象
            if (!modelData.geometry) {
                console.error('[ModelContext] 创建几何体模型失败: 缺少几何体信息');
                throw new Error('缺少几何体信息');
            }
            const response = await modelService.createModel(modelData);
            console.log('[ModelContext] 创建几何体模型成功:', response.data?.modelId || response.data?.data?.id);
            // 添加新模型到状态
            await fetchModels(); // 重新获取所有模型
            return response;
        } catch (err) {
            console.error('[ModelContext] 创建几何体模型失败:', err);
            setError('创建几何体模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 更新模型
    const updateModel = useCallback(async (modelId, modelData) => {
        setLoading(true);
        setError(null);
        try {
            const response = await modelService.updateModel(modelId, modelData);
            // 更新模型状态
            // 由于更新后的API响应不返回完整的更新后模型数据，需要刷新列表
            await fetchModels();
            return response;
        } catch (err) {
            console.error('更新模型失败:', err);
            setError('更新模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 更新外部模型属性
    const updateExternalModel = useCallback(async (modelId, updateData) => {
        setLoading(true);
        setError(null);
        try {
            const response = await fileService.updateExternalModel(modelId, updateData);
            // 更新模型列表
            await fetchModels();
            return response;
        } catch (err) {
            console.error('更新外部模型属性失败:', err);
            setError('更新外部模型属性失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 更新模型几何体
    const updateModelGeometry = useCallback(async (modelId, geometryData) => {
        setLoading(true);
        setError(null);
        try {
            // 确保geometryData包含geometry和additionalObjects字段
            const modelData = {
                geometry: geometryData.geometry || geometryData,
                additionalObjects: geometryData.additionalObjects || [],
                // 添加对外部模型的支持
                externalModels: geometryData.externalModels || []
            };

            // 打印完整模型数据以便调试
            console.log('正在更新模型几何体:', modelId, modelData);

            const response = await modelService.updateModel(modelId, modelData);

            // 更新模型状态 - 使用fetchModels刷新列表
            await fetchModels();
            return response;
        } catch (err) {
            console.error('更新模型几何体失败:', err);
            setError('更新模型几何体失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 删除模型
    const deleteModel = useCallback(async (modelId) => {
        setLoading(true);
        setError(null);
        try {
            // 确保模型ID是字符串类型
            const id = String(modelId);

            const response = await modelService.deleteModel(id);

            // 从状态中移除模型 - 基于ID
            setModels(prevModels => prevModels.filter(model => String(model.id) !== id));

            return response;
        } catch (err) {
            const errorMessage = err.message || '删除模型失败，请稍后再试';
            console.error('删除模型失败:', errorMessage, err);
            setError(errorMessage);
            throw err;
        } finally {
            setLoading(false);
        }
    }, []);

    // 上传模型文件
    const uploadModelFile = useCallback(async (modelId, file) => {
        setFileLoading(true);
        setFileError(null);
        setUploadProgress(0);

        try {
            // 创建上传进度模拟
            const progressInterval = setInterval(() => {
                setUploadProgress(prev => {
                    const newProgress = prev + Math.random() * 10;
                    return newProgress >= 95 ? 95 : newProgress;
                });
            }, 300);

            const response = await fileService.uploadModelFile(modelId, file);

            clearInterval(progressInterval);
            setUploadProgress(100);

            // 更新模型信息，标记为已有文件
            setModels(prevModels =>
                prevModels.map(model =>
                    model.id === modelId ? { ...model, hasFile: true } : model
                )
            );

            return response;
        } catch (err) {
            console.error('上传模型文件失败:', err);
            setFileError('上传模型文件失败，请稍后再试');
            throw err;
        } finally {
            setFileLoading(false);
            // 重置进度条在一小段延迟后
            setTimeout(() => setUploadProgress(0), 1000);
        }
    }, []);

    // 一步创建和上传外部模型
    const createAndUploadExternalModel = useCallback(async (modelData, file) => {
        setLoading(true);
        setFileLoading(true);
        setError(null);
        setFileError(null);
        setUploadProgress(0);

        try {
            // 创建上传进度模拟
            const progressInterval = setInterval(() => {
                setUploadProgress(prev => {
                    const newProgress = prev + Math.random() * 10;
                    return newProgress >= 95 ? 95 : newProgress;
                });
            }, 300);

            const response = await fileService.createAndUploadExternalModel(modelData, file);

            clearInterval(progressInterval);
            setUploadProgress(100);

            // 刷新模型列表
            await fetchModels();

            return response;
        } catch (err) {
            console.error('一步创建和上传外部模型失败:', err);
            setError('创建和上传模型失败，请稍后再试');
            setFileError('创建和上传模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
            setFileLoading(false);
            // 重置进度条在一小段延迟后
            setTimeout(() => setUploadProgress(0), 1000);
        }
    }, [fetchModels]);

    // 导入外部模型
    const importExternalModel = useCallback(async (file, modelData = {}) => {
        setLoading(true);
        setFileLoading(true);
        setError(null);
        setFileError(null);
        setUploadProgress(0);

        try {
            // 创建上传进度模拟
            const progressInterval = setInterval(() => {
                setUploadProgress(prev => {
                    const newProgress = prev + Math.random() * 10;
                    return newProgress >= 95 ? 95 : newProgress;
                });
            }, 300);

            const response = await fileService.importExternalModel(file, modelData);

            clearInterval(progressInterval);
            setUploadProgress(100);

            // 刷新模型列表
            await fetchModels();

            return response;
        } catch (err) {
            console.error('导入外部模型失败:', err);
            setError('导入模型失败，请稍后再试');
            setFileError('导入模型失败，请稍后再试');
            throw err;
        } finally {
            setLoading(false);
            setFileLoading(false);
            // 重置进度条在一小段延迟后
            setTimeout(() => setUploadProgress(0), 1000);
        }
    }, [fetchModels]);

    // 从服务器URL加载模型
    const loadModelFromServerUrl = useCallback(async (url) => {
        setLoading(true);
        setError(null);

        try {
            const response = await fileService.tryLoadModelFromServer(url);

            // 刷新模型列表
            await fetchModels();

            return response;
        } catch (err) {
            console.error('从服务器URL加载模型失败:', err);
            setError('从服务器URL加载模型失败，请检查URL是否正确');
            throw err;
        } finally {
            setLoading(false);
        }
    }, [fetchModels]);

    // 下载模型文件
    const downloadModelFile = useCallback(async (modelId, format = null) => {
        setFileLoading(true);
        setFileError(null);

        try {
            const response = await fileService.downloadModelFile(modelId, format);
            return response;
        } catch (err) {
            console.error('下载模型文件失败:', err);
            setFileError('下载模型文件失败，请稍后再试');
            throw err;
        } finally {
            setFileLoading(false);
        }
    }, []);

    // 获取模型缩略图
    const getModelThumbnail = useCallback(async (modelId) => {
        try {
            const response = await fileService.getModelThumbnail(modelId);
            return response.thumbnailUrl || response.data?.thumbnail;
        } catch (err) {
            console.error('获取模型缩略图失败:', err);
            // 不设置全局错误状态，允许静默失败并显示占位图
            return null;
        }
    }, []);

    // 初始化时获取数据 - 使用useRef确保只初始化一次
    useEffect(() => {
        if (!isInitialized.current) {
            isInitialized.current = true;
            fetchModels();
            fetchGeometryTypes();
        }
    }, [fetchModels, fetchGeometryTypes]);  // 添加依赖项

    const value = {
        models,
        loading,
        error,
        fetchModels,
        createModel,
        createGeometryModel,
        createExternalModel,
        updateModel,
        updateExternalModel,
        updateModelGeometry,
        deleteModel,
        geometryTypes,
        geometryTypesLoading,
        geometryTypesError,
        fetchGeometryTypes,
        fileLoading,
        fileError,
        uploadProgress,
        uploadModelFile,
        createAndUploadExternalModel,
        importExternalModel,
        loadModelFromServerUrl,
        downloadModelFile,
        getModelThumbnail,
    };

    return (
        <ModelContext.Provider value={value}>
            {children}
        </ModelContext.Provider>
    );
};

export default ModelContext; 